package com.cah.project.module.standard.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cah.project.core.dict.cache.DictDataCache;
import com.cah.project.core.dict.domain.vo.DictDataOptions;
import com.cah.project.core.domain.out.PageList;
import com.cah.project.core.util.PageUtil;
import com.cah.project.enums.YesOrNoEnum;
import com.cah.project.exception.BusinessException;
import com.cah.project.module.standard.domain.converter.DictConverter;
import com.cah.project.module.standard.domain.entity.DictDataEntity;
import com.cah.project.module.standard.domain.vo.DictDataInfo;
import com.cah.project.module.standard.domain.vo.in.DictDataQuery;
import com.cah.project.module.standard.domain.vo.out.DictDataList;
import com.cah.project.module.standard.mapper.DictDataMapper;
import com.cah.project.module.standard.service.IDictDataService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.List;

/**
 * 功能描述: 字典数据 服务实现 <br/>
 */
@Service
@RequiredArgsConstructor(onConstructor_ = {@Autowired, @Lazy})
public class DictDataServiceImpl extends ServiceImpl<DictDataMapper, DictDataEntity> implements IDictDataService {

    @Override
    public DictDataInfo selectById(String typeCode, String id) {
        DictDataInfo info;
        if(StrUtil.isEmpty(id)) {
            info = new DictDataInfo();
            info.setTypeCode(typeCode);
        } else {
            DictDataEntity entity = getById(id);
            info = DictConverter.INSTANCE.toDictDataInfo(entity);
        }
        info.setTypeName(DictDataCache.getTypeName(info.getTypeCode()));
        return info;
    }

    @Override
    public PageList<DictDataList> pageList(DictDataQuery query) {
        IPage<DictDataEntity> page = lambdaQuery()
                .like(StrUtil.isNotEmpty(query.getTypeCode()), DictDataEntity::getTypeCode, query.getTypeCode())
                .page(PageUtil.buildPage(query));
        // 对象转换
        List<DictDataList> list = DictConverter.INSTANCE.toDictDataList(page.getRecords());
        return new PageList<>(PageUtil.buildPageInfo(page), list);
    }

    @Override
    public void saveInfo(DictDataInfo info) {
        DictDataEntity entity = DictConverter.INSTANCE.toDictDataEntity(info);
        // 通过 类型代码，查询数据，校验 键值或代码值不能重复。
        List<DictDataEntity> dbList = selectListByCode(info.getTypeCode());
        if(CollUtil.isNotEmpty(dbList)) {
            dbList.forEach(e -> {
                if((StrUtil.equals(e.getDataKey(), info.getDataKey()) || StrUtil.equals(e.getDataValue(), info.getDataValue()))
                        && !e.getId().equals(info.getId())) {
                    throw new BusinessException("已经存在键值或代码值相同的数据。");
                }
            });
        }
        if(ObjectUtil.isEmpty(entity.getId())) {
            entity.setEnable(YesOrNoEnum.YES.getIndex());
        }
        saveOrUpdate(entity);
    }

    @Override
    public void updateEnable(String id, YesOrNoEnum enable) {
        DictDataEntity entity = new DictDataEntity();
        entity.setId(Long.valueOf(id));
        entity.setEnable(enable.getIndex());
        updateById(entity);
    }

    @Override
    public List<DictDataOptions> selectDataOptionsByCode(String dictType) {
        return DictDataCache.get(dictType);
    }

    @Override
    public List<DictDataOptions> selectDataOptionsByLoadType(String loadType, String dictType) {
        return DictDataCache.get(loadType, dictType);
    }

    @Override
    public List<DictDataEntity> selectListByCode(String dictType) {
        return lambdaQuery().eq(DictDataEntity::getTypeCode, dictType)
                .eq(DictDataEntity::getEnable, YesOrNoEnum.YES.getCode()).list();
    }

    @Override
    public List<DictDataEntity> selectListByCodes(Collection<String> dictTypeList) {
        if(CollUtil.isEmpty(dictTypeList)) {
            return ListUtil.empty();
        }
        return lambdaQuery().in(DictDataEntity::getTypeCode, dictTypeList)
                .eq(DictDataEntity::getEnable, YesOrNoEnum.YES.getCode()).list();
    }

}
